//
//  TwitterApp.swift
//  Twitter
//
//  Created by Hoa.wang on 2022/3/30.
//

import SwiftUI
import ParseSwift

@main
struct TwitterApp: App {
    
    @StateObject var viewModel = AuthViewModel()
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    init() {
        ParseSwift.initialize(applicationId: "com.hoa.test", masterKey: "test123456", serverURL: URL(string: "http://119.91.119.253:1337/parse")!)
    }
    
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
            .environmentObject(viewModel)
        }
    }
}
//*** Implement App delegate ***//
class AppDelegate: NSObject, UIApplicationDelegate {
    
    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            print("Notification settings: \(settings)")
            guard settings.authorizationStatus == .authorized else {
                return
            }
            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (allowed, error) in
                 //This callback does not trigger on main loop be careful
                if allowed {
                    DispatchQueue.main.async {
                        UIApplication.shared.registerForRemoteNotifications()
                    }
                } else {
                    print("----false")
                }
            }
        }
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        getNotificationSettings()
        return true
    }

    func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        createInstallationOnParse(deviceTokenData: deviceToken)
    }

    func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register: \(error)")
    }

    func createInstallationOnParse(deviceTokenData:Data){
        
        var installation = PInstallation.current
        installation?.deviceToken = deviceTokenData.base64EncodedString()
        if let uid = User.current?.objectId {
            installation?.uid = uid
        }
        installation?.save {  result in
            switch result {
            case .success(let inst):
                print("DEBUG: DeviceToken created success. \(inst)")
            case .failure(let error):
                print("DEBUG: Failed to create installation with error: \(error.localizedDescription)")
            }
        }
        
    }
    
}

struct PInstallation: ParseInstallation {
    var deviceType: String?
    
    var installationId: String?
    
    var deviceToken: String?
    
    var badge: Int?
    
    var timeZone: String?
    
    var channels: [String]?
    
    var appName: String?
    
    var appIdentifier: String?
    
    var appVersion: String?
    
    var parseVersion: String?
    
    var localeIdentifier: String?
    
    var originalData: Data?
    
    var objectId: String?
    
    var createdAt: Date?
    
    var updatedAt: Date?
    
    var ACL: ParseACL?
    
    var uid: String?
    
    func merge(with object: Self) throws -> Self {
        var updated = try mergeParse(with: object)
        if updated.shouldRestoreKey(\.uid, original: object) {
            updated.uid = object.uid
        }
        return updated
    }
}
